package com.douqu.game.core.config.drop;

import com.bean.core.util.Utils;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.E_DropGroupType;
import com.douqu.game.core.e.E_DropType;
import com.douqu.game.core.entity.GameObject;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.util.LoadUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author: Gavin
 * Description: 掉落
 * Date: 2017-08-03 16:29-29
 * Huan Yu Copyright (c) 2017 All Rights Reserved.
 */

public class DropGroupConfig extends GameObject {

    /**
     * 对应E_DropType枚举里的值
     */
    public int propType; //道具掉落类型

    public int assetType; //资源掉落类型

    public int cardType; //兵种掉落类型

    public DropObject[] props; //道具掉落配置

    public DropObject[] assets; //资源掉落配置

    public DropObject[] cards; //卡片掉落配置

    public int type;        //类型


    /**
     * 领取奖励
     *
     * @param playerController
     */
    public void reward(PlayerController playerController) {
        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);

        List<DropObject> cards = getCardList();
        for (DropObject dropObject : cards) {
            bagInfo.addCard(dropObject.id, dropObject.count);
        }
        //掉落的道具
        List<DropObject> props = getPropList();
        for (DropObject dropObject : props) {
            bagInfo.addProp(dropObject.id, dropObject.count);
        }
        /*Map<Integer, CommonData> cardPropMap = new ConcurrentHashMap<>();
        //掉落的道具
        List<DropObject> props = getPropList();
        int tempCount = 0;
        for(DropObject dropObject : props) {
            if(cardPropMap.get(dropObject.id) != null) {
                tempCount = dropObject.count + cardPropMap.get(dropObject.id).value;
                cardPropMap.remove(dropObject.id);
            } else {
                tempCount = dropObject.count;
            }

            bagInfo.addProp(dropObject.id, tempCount);
        }
        //掉落卡牌碎片
        for(Map.Entry<Integer, CommonData> entry : cardPropMap.entrySet())
        {
            bagInfo.addProp(entry.getKey(), entry.getValue().value);
        }*/

        //掉落的资源
        List<DropObject> assets = getAssetList();
        for (DropObject dropObject : assets) {
            bagInfo.addAsset(dropObject.id, dropObject.count);
        }
    }

    public void reward(PlayerController playerController, int count) {
        BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
        /**
         * 原来的掉落没有判断type
         */
        for (int i= 0;i < count;i++){
            dropRewardResult(bagInfo);
        }
//        Map<Integer, Integer> cardMap = new HashMap<>();
//        Map<Integer, Integer> propMap = new HashMap<>();
//        Map<Integer, Integer> assetsMap = new HashMap<>();
//
//        for (int i = 0; i < count; i++) {
//            List<DropObject> cards = getCardList();
//            for (DropObject dropObject : cards) {
//                //合并方法 如果id存在则 id的value为原value + count
//                //如果id不存在 设置id的value为object
//                cardMap.merge(dropObject.id, dropObject.count, (v1, v2) -> v1 + v2);
//            }
//            //掉落的道具
//            List<DropObject> props = getPropList();
//            for (DropObject dropObject : props) {
//                propMap.merge(dropObject.id, dropObject.count, (v1, v2) -> v1 + v2);
//            }
//
//            //掉落的资源
//            List<DropObject> assets = getAssetList();
//            for (DropObject dropObject : assets) {
//                assetsMap.merge(dropObject.id, dropObject.count, (v1, v2) -> v1 + v2);
//            }
//        }
//
//        if (!cardMap.isEmpty()) {
//            for (Map.Entry<Integer, Integer> e : cardMap.entrySet()) {
//                bagInfo.addCard(e.getKey(), e.getValue());
//            }
//        }
//        if (!propMap.isEmpty()) {
//            for (Map.Entry<Integer, Integer> e : propMap.entrySet()) {
//                bagInfo.addProp(e.getKey(), e.getValue());
//            }
//        }
//        if (!assetsMap.isEmpty()) {
//            for (Map.Entry<Integer, Integer> e : assetsMap.entrySet()) {
//                bagInfo.addAsset(e.getKey(), e.getValue());
//            }
//        }
    }

    /**
     * 领取奖励
     *
     * @param bagInfo
     */
    public void dropRewardOnce(BagInfo bagInfo) {

        //掉落的卡牌
        for (DropObject dropObject : getCardList()) {
            bagInfo.addCard(dropObject.id, dropObject.count);
        }

        //掉落的道具
        for (DropObject dropObject : getPropList()) {
            bagInfo.addProp(dropObject.id, dropObject.count);
        }

        //掉落的资源
        for (DropObject dropObject : getAssetList()) {
            bagInfo.addAsset(dropObject.id, dropObject.count);
        }
    }

    public void dropRewardResult(BagInfo bagInfo) {
        if (type == E_DropGroupType.SINGLE.getCode()) {
            dropRewardOnce(bagInfo);
        } else if (type == E_DropGroupType.WHOLE.getCode()) {
            dropRewardAll(bagInfo);
        }
    }

    /***
     * 获取掉落的道具List
     * @return
     */
    public List<DropObject> getPropList() {
        List<DropObject> propList = new CopyOnWriteArrayList<DropObject>();
        if (propType == E_DropType.RANDOM.getCode()) {
            //根据概率计算是否掉落
            for (int i = 0; i < props.length; i++) {
                if (Utils.checkRandom10000(props[i].odds)) {
                    propList.add(props[i]);
                }
            }
        } else if (propType == E_DropType.ONLY_ONE.getCode() && props.length > 0) {
            int c = 0;
            for (int i = 0; i < props.length; i++) {
                c += props[i].odds;
            }
            int r = Utils.getRandom(c);
            int temp = 0;
            for (int j = 0; j < props.length; j++) {
                temp += props[j].odds;
                if (r <= temp) {
                    propList.add(props[j]);
                    break;
                }
            }
        }

        return propList;
    }

    /***
     * 获取资源list
     * @return
     */
    public List<DropObject> getAssetList() {
        List<DropObject> assetList = new ArrayList<DropObject>();
        if (assetType == E_DropType.RANDOM.getCode()) {
            //根据概率计算是否中
            for (int i = 0; i < assets.length; i++) {
                if (Utils.checkRandom10000(assets[i].odds)) {
                    assetList.add(assets[i]);
                }
            }
        } else if (assetType == E_DropType.ONLY_ONE.getCode() && assets.length > 0) {
            int c = 0;
            for (int i = 0; i < assets.length; i++) {
                c += assets[i].odds;
            }
            int r = Utils.getRandom(c);
            int temp = 0;
            for (int j = 0; j < assets.length; j++) {
                temp += assets[j].odds;
                if (r <= temp) {
                    assetList.add(assets[j]);
                    break;
                }
            }
        }

        return assetList;
    }


    /***
     * 获取资源list
     * @return
     */
    public List<DropObject> getCardList() {
        /**
         * 如果cardType是1 每个物品判断一次是否成功掉落
         *     cardType是2 所有物品里选择一个去掉落
         */
        List<DropObject> cardList = new ArrayList<DropObject>();
        if (cardType == E_DropType.RANDOM.getCode()) {
            //根据概率计算是否中
            for (int i = 0; i < cards.length; i++) {
                if (Utils.checkRandom10000(cards[i].odds)) {
                    cardList.add(cards[i]);
                }
            }
        } else if (cardType == E_DropType.ONLY_ONE.getCode() && cards.length > 0) {
            int c = 0;
            for (int i = 0; i < cards.length; i++) {
                c += cards[i].odds;
            }

            int r = Utils.getRandom(c);
            int temp = 0;
            for (int j = 0; j < cards.length; j++) {
                temp += cards[j].odds;
                if (r <= temp) {
                    cardList.add(cards[j]);
                    break;
                }
            }
        }

        return cardList;
    }


    /***
     * 所有的类型一起掉落
     * @return
     */
    public void dropRewardAll(BagInfo bagInfo) {
        int c = 0;
        for (int i = 0; i < props.length; i++) {
            c += props[i].odds;
        }

        for (int i = 0; i < assets.length; i++) {
            c += assets[i].odds;
        }

        for (int i = 0; i < cards.length; i++) {
            c += cards[i].odds;
        }
        if (c > 0) {
            int r = Utils.getRandom(c);
            int temp = 0;
            for (int j = 0; j < props.length; j++) {
                temp += props[j].odds;
                if (r <= temp) {
                    bagInfo.addProp(props[j].id, props[j].count);
                    return;
                }
            }
            for (int j = 0; j < assets.length; j++) {
                temp += assets[j].odds;
                if (r <= temp) {
                    bagInfo.addAsset(assets[j].id, assets[j].count);
                    return;
                }
            }

            TwoTuple<CommonData, CommonData> tempCommonData = null;
            for (int j = 0; j < cards.length; j++) {
                temp += cards[j].odds;
                if (r <= temp) {
                    bagInfo.addCard(cards[j].id, cards[j].count);
                    return;
                }
            }
        }
    }


    @Override
    public boolean setVariable(String key, String value) {
        if ("props".equals(key)) {
            props = LoadUtils.loadDropObject(value);
            return LoadUtils.checkDropObject(props, this.getClass(), key, DataFactory.PROP_KEY, id);
        } else if ("assets".equals(key)) {
            assets = LoadUtils.loadDropObject(value);
            return LoadUtils.checkDropObject(assets, this.getClass(), key, DataFactory.ASSET_KEY, id);
        } else if ("cards".equals(key)) {
            cards = LoadUtils.loadDropObject(value);
            return LoadUtils.checkDropObject(cards, this.getClass(), key, DataFactory.CARD_KEY, id);
        } else
            return super.setVariable(key, value);

    }


}
